package com.zhigh.project.security.jwt.authentication;

import com.alibaba.fastjson.JSON;
import lombok.Builder;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.util.List;
import java.util.Map;

/**
 * JWT 负载的基本的内容
 * -
 * sub: Subject(主体)
 * iss: issuer(Token签发者)
 * aud: audience(Token受众)
 * exp: expirationTime(Token过期时间)
 * nbf: notBeforeTime(Token生效开始时间)
 * iat: issueTime(Token签发时间)
 * jti: jwtID(jwt id)
 */
@Builder
public class DefaultJWTPayload implements JWTPayload {
    /**
     * 主题
     */
    private String sub;

    /**
     * issuer(Token签发者)
     */
    private String iss;

    /**
     * Token受众
     */
    private List<String> aud;

    /**
     * 过期时间
     */
    private Long exp;

    /**
     * Token生效开始时间
     */
    private Long nbf;
    /**
     * 签发时间
     */
    private Long iat;
    /**
     * id
     */
    private String jti;
    /**
     * 用户名
     */
    private String username;
    /**
     * 权限
     */
    private List<String> authorities;

    /**
     * 额外数据
     */
    private Map<String, Object> additional;


    public DefaultJWTPayload() {
    }

    public DefaultJWTPayload(String sub, String iss, List<String> aud, Long exp, Long nbf, Long iat, String jti, String username, List<String> authorities, Map<String, Object> additional) {
        this.sub = sub;
        this.iss = iss;
        this.aud = aud;
        this.exp = exp;
        this.nbf = nbf;
        this.iat = iat;
        this.jti = jti;
        this.username = username;
        this.authorities = authorities;
        this.additional = additional;
    }

    @Override
    public String getSub() {
        return sub;
    }

    public void setSub(String sub) {
        this.sub = sub;
    }

    @Override
    public Long getIat() {
        return iat;
    }

    public void setIat(Long iat) {
        this.iat = iat;
    }

    @Override
    public Long getExp() {
        return exp;
    }

    public void setExp(Long exp) {
        this.exp = exp;
    }

    @Override
    public String getJti() {
        return jti;
    }

    public void setJti(String jti) {
        this.jti = jti;
    }

    @Override
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Override
    public List<String> getAuthorities() {
        return authorities;
    }

    public void setAuthorities(List<String> authorities) {
        this.authorities = authorities;
    }

    @Override
    public Map<String, Object> getAdditional() {
        return additional;
    }


    public void setAdditional(Map<String, Object> additional) {
        this.additional = additional;
    }

    @Override
    public String getIss() {
        return iss;
    }

    public void setIss(String iss) {
        this.iss = iss;
    }

    @Override
    public List<String> getAud() {
        return aud;
    }

    public void setAud(List<String> aud) {
        this.aud = aud;
    }

    @Override
    public Long getNbf() {
        return nbf;
    }

    public void setNbf(Long nbf) {
        this.nbf = nbf;
    }

    @Override
    public String toPayloadStr() {
        return JSON.toJSONString(this);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;

        if (o == null || getClass() != o.getClass()) return false;

        DefaultJWTPayload that = (DefaultJWTPayload) o;

        return new EqualsBuilder().append(sub, that.sub).append(iss, that.iss).append(aud, that.aud).append(exp, that.exp).append(nbf, that.nbf).append(iat, that.iat).append(jti, that.jti).append(username, that.username).append(authorities, that.authorities).append(additional, that.additional).isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 37).append(sub).append(iss).append(aud).append(exp).append(nbf).append(iat).append(jti).append(username).append(authorities).append(additional).toHashCode();
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)
                .append("sub", sub)
                .append("iss", iss)
                .append("aud", aud)
                .append("exp", exp)
                .append("nbf", nbf)
                .append("iat", iat)
                .append("jti", jti)
                .append("username", username)
                .append("authorities", authorities)
                .append("additional", additional)
                .toString();
    }
}
